﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SceneManager
{
	public class Scene
	{
		#region Variables

		private List<GameObject> _gameObjects;

		#endregion

		#region Constructors

		public Scene()
		{
			_gameObjects = new List<GameObject>();

			ApplyGravity = ApplyGravity_NoGravity;
		}

		#endregion

		#region Properties

		public SpriteBatch SpriteBatch { get; private set; }

		public ReadOnlyCollection<GameObject> GameObjects
		{
			get
			{
				return new ReadOnlyCollection<GameObject>(_gameObjects);
			}
		}

		public Action<GameObject> ApplyGravity { get; set; }

		#endregion

		#region Methods

		private static void ApplyGravity_NoGravity(GameObject obj)
		{
		}

		public void AddObject(GameObject obj)
		{
			obj.Scene = this;
			_gameObjects.Add(obj);
		}

		public void RemoveObject(GameObject obj)
		{
			if (_gameObjects.Contains(obj))
			{
				_gameObjects.Remove(obj);
			}
		}

		public IEnumerable<GameObject> Find(string name)
		{
			return _gameObjects.Where(obj => obj.Name == name);
		}

		public void LoadContent(GraphicsDevice graphicsDevice)
		{
			SpriteBatch = new SpriteBatch(graphicsDevice);
		}

		public void UnloadContent()
		{
			SpriteBatch = null;
		}

		public void Update(GameTime gameTime)
		{
			foreach (var gameObject in _gameObjects)
			{
				gameObject.Update(gameTime);
			}
		}

		public void Draw(GameTime gameTime)
		{
			SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

			foreach (var gameObject in _gameObjects)
			{
				gameObject.Draw(gameTime);
			}

			SpriteBatch.End();
		}

		#endregion
	}
}